<template>
  <div class="list-common-table">
    <!--   搜索部分   -->
    <t-form
      v-if="searchParams && searchParams.length"
      ref="form"
      :data="formData"
      :label-width="80"
      colon
      @reset="onReset"
      @submit="onSearch"
    >
      <t-row>
        <t-col :span="10">
          <t-row :gutter="[24, 24]">
            <t-col v-for="(item, index) in searchParams" :key="index" :span="4">
              <template v-if="!item.hide">
                <t-form-item :label="item.label" :name="item.key">
                  <t-input v-if="item.valueType !== 'select'" v-model="formData[`${item.key}`]" clearable />
                  <t-select v-else v-model="formData[`${item.key}`]" :options="item.options" clearable />
                </t-form-item>
              </template>
            </t-col>
          </t-row>
        </t-col>
        <t-col :span="2" class="operation-container">
          <t-button theme="primary" type="submit" :style="{ marginLeft: 'var(--td-comp-margin-s)' }">
            {{ t('components.commonTable.query') }}
          </t-button>
          <t-button type="reset" variant="base" theme="default">
            {{ t('components.commonTable.reset') }}
          </t-button>
        </t-col>
      </t-row>
    </t-form>
    <div class="table-header">
      <slot name="tableHeader"></slot>
    </div>
    <div class="table-container">
      <t-enhanced-table
        v-if="tree"
        :row-key="rowKey"
        table-layout="auto"
        :data="data"
        :columns="columns"
        :selected-row-keys="selectedRowKeys"
        :pagination="pagination"
        :loading="loading"
        :tree="treeConfig"
        @select-change="onSelectedRowKeys"
      />
      <t-table
        v-else
        :data="data"
        table-layout="auto"
        :columns="columns"
        :row-key="rowKey"
        :max-height="500"
        :selected-row-keys="selectedRowKeys"
        :pagination="pagination"
        :loading="loading"
        @select-change="onSelectedRowKeys"
        @page-change="pageChange"
      />
    </div>
  </div>
</template>
<script setup lang="ts">
import { FormInstanceFunctions, PageInfo, PaginationProps, TableTreeConfig } from 'tdesign-vue-next';
import { onMounted, PropType, ref } from 'vue';

import { t } from '@/locales';

interface SearchFormData {
  [key: string]: any;
}

const form = ref<FormInstanceFunctions>(null);
const formData = ref<SearchFormData>({});
const data = ref([]);
const selectedRowKeys = ref([]);
const loading = ref(false);
const props = defineProps({
  /** 搜索参数 */
  searchParams: {
    type: Array as PropType<_SearchParamsProps[]>,
  },
  /** 表格列配置 */
  columns: {
    type: Array,
  },
  /** 表格行key */
  rowKey: {
    type: String,
    default: 'id',
  },
  /** 分页配置 */
  pageConfig: {
    type: Object,
  },
  pageSizes: {
    type: Array<
      | number
      | {
          label: string;
          value: number;
        }
    >,
    default: () => [10, 20, 50, 100],
  },
  /** 接口请求函数 */
  asyncFc: {
    type: Function,
  },
  /** 是否分页 */
  page: {
    type: Boolean,
    default: true,
  },
  /** 是否为树形结构表格 */
  tree: {
    type: Boolean,
    default: false,
  },
  /** 树形结构配置 */
  treeConfig: {
    type: Object as PropType<TableTreeConfig>,
    default: () => ({ childrenKey: 'children' }),
  },
});
/**
 * 组件初始进来，判断是否存在表单项默认值
 */
if (props.searchParams && props.searchParams.length) {
  const data: SearchFormData = {};
  // 迭代表单项
  props.searchParams.forEach((item) => {
    // 如果存在默认值 null undefined 0 '0'
    if (item.defaultValue || item.defaultValue === 0) {
      // 将表单项value-v-model赋值
      data[item.key] = item.defaultValue;
    }
  });
  formData.value = data;
}

/**
 * 分页配置
 */
const pagination = ref<PaginationProps>(
  props.page
    ? {
        defaultCurrent: props.pageConfig?.pageNo || 1,
        defaultPageSize: props.pageConfig?.pageSize || 10,
        total: 0,
        pageSizeOptions: props.pageSizes,
      }
    : null,
);

/**
 * 查询数据
 * @param pageNo 页码
 * @param pageSize 页大小
 * @param params 查询参数
 */
const findData = async (pageNo: number, pageSize: number, params: any) => {
  loading.value = true;
  try {
    const response = await props.asyncFc(props.page ? { pageNo, pageSize, params } : params);
    if (props.page) {
      data.value = response.records;
      pagination.value = {
        ...pagination.value,
        current: pageNo,
        pageSize,
        total: response.total,
      };
    } else {
      data.value = response;
    }
  } catch (e) {
    console.log(e);
  } finally {
    loading.value = false;
  }
};

/**
 * 重置表单
 */
const onReset = () => {
  form.value.reset();
  findData(pagination.value?.defaultCurrent, pagination.value?.defaultPageSize, { ...formData.value });
};

/**
 * 查询数据
 * @param params 查询参数
 */
const onSearch = (params?: any) => {
  findData(pagination.value?.current || 1, pagination.value?.pageSize || 10, { ...formData.value, ...params });
};

/**
 * 分页变化
 * @param pageInfo 分页信息
 */
const pageChange = ({ current, pageSize }: PageInfo) => {
  findData(current, pageSize, formData.value);
};

/**
 * 选择行
 * @param value 选择行key
 */
const onSelectedRowKeys = (value: any[]) => {
  selectedRowKeys.value = value;
};

/**
 * 组件初始化
 */
onMounted(() => {
  findData(pagination.value?.defaultCurrent, pagination.value?.defaultPageSize, formData.value);
});

/**
 * 子组件暴露给父组件调用的方法
 */
defineExpose({ onSearch, getSelectedKeys: () => selectedRowKeys.value });
</script>
<style lang="less" scoped>
.list-common-table {
  background-color: var(--td-bg-color-container);
  padding: 30px 20px;
  border-radius: var(--td-radius-medium);

  .table-header {
    margin-top: var(--td-comp-margin-xxl);
  }

  .table-container {
    margin-top: var(--td-comp-margin-xl);
  }
}

.form-item-content {
  width: 100%;
}

.operation-container {
  display: flex;
  justify-content: flex-end;
  align-items: center;

  .expand {
    .t-button__text {
      display: flex;
      align-items: center;
    }
  }
}

.payment-col {
  display: flex;

  .trend-container {
    display: flex;
    align-items: center;
    margin-left: var(--td-comp-margin-s);
  }
}
</style>
